package com.kehutong.common.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.coraframework.json.JSONObject;
import org.coraframework.json.annotation.JSONField;
import org.coraframework.orm.util.Enums;
import org.coraframework.util.Objects;
import org.coraframework.util.SessionId;

import com.kehutong.common.enums.UserType;

public class Token implements java.io.Serializable, SessionId {
	
	private static final long serialVersionUID = 1386988946054088554L;

	/**sessionId*/
	private String sessionId;

	/**企业id*/
    private String companyNo;

    /** 企业名称*/
    private String companyName;
    
    /** 主部门*/
    private List<String> departments;
	
    /**企微企业id*/
    private String corpid;

    /**当前使用应用id*/
    private String suiteId;
    
    /**用户id*/
    private String uuid;

    /**用户id,对应企业微信id*/
    private String userId;

    /** 用户昵称*/
	private String username;

	/** 用户手机号*/
    private String mobile;

    /** 用户头像*/
    private String headUrl;
    
    /** 角色*/
    private Set<String> roles;
    
    /** 用户权限*/
    private Set<String> permissions;
    
    /** 登陆类型*/
    private UserType userType;

    /** 上次提醒时间*/
	private Long remindTime;
    
    /** 创建时间*/
    private long timestamp;

    /** 账号创建时间*/
    private long userCreateTime;

	/** 版本*/
    private String version;

	/** 拓展信息*/
    private String extContent;

    private String oldKhtUrl;

	private boolean newsletterState;

	private boolean frontPageState;

	private boolean businessState;

	private boolean settingState;

	/** 公司模板 0.第三方 1.内建*/
	private String cropPattern;

    /** httpServletRequest*/
    @JSONField(serialize=false, deserialize=false)
	private HttpServletRequest req;

	/** HttpServletResponse*/
    @JSONField(serialize=false, deserialize=false)
	private HttpServletResponse resp;

	public String getSessionId() {
		return sessionId;
	}

	public Token setSessionId(String sessionId) {
		this.sessionId = sessionId;
		return this;
	}

	public String getCompanyNo() {
		return companyNo;
	}

	public Token setCompanyNo(String companyNo) {
		this.companyNo = companyNo;
		return this;
	}

	public String getCompanyName() {
		return companyName;
	}

	public Token setCompanyName(String companyName) {
		this.companyName = companyName;
		return this;
	}

	public String getCorpid() {
		return corpid;
	}

	public Token setCorpid(String corpid) {
		this.corpid = corpid;
		return this;
	}

	public String getSuiteId() {
		return suiteId;
	}

	public Token setSuiteId(String suiteId) {
		this.suiteId = suiteId;
		return this;
	}

	public String getUuid() {
		return uuid;
	}

	public Token setUuid(String uuid) {
		this.uuid = uuid;
		return this;
	}

	public String getUserId() {
		return userId;
	}

	public Token setUserId(String userId) {
		this.userId = userId;
		return this;
	}
	
	public String getName() {
		return username;
	}

	public String getUsername() {
		return username;
	}

	public Token setUsername(String username) {
		this.username = username;
		return this;
	}

	public String getMobile() {
		return mobile;
	}

	public Token setMobile(String mobile) {
		this.mobile = mobile;
		return this;
	}

	public String getHeadUrl() {
		return headUrl;
	}

	public Token setHeadUrl(String headUrl) {
		this.headUrl = headUrl;
		return this;
	}
	
	
	public UserType getUserType() {
		return userType;
	}

	public Token setUserType(UserType userType) {
		this.userType = userType;
		return this;
	}

	public Set<String> getPermissions() {
		if (Objects.isNull(permissions)) {
			return Collections.emptySet();
		}
		return permissions;
	}

	public Token setPermissions(Set<String> permissions) {
		this.permissions = permissions;
		return this;
	}

	public Set<String> getRoles() {
		if (Objects.isNull(roles)) {
			return Collections.emptySet();
		}
		return roles;
	}

	public Token setRoles(Set<String> roles) {
		this.roles = roles;
		return this;
	}

	public HttpServletRequest getReq() {
		return req;
	}

	public Token setReq(HttpServletRequest req) {
		this.req = req;
		return this;
	}

	public HttpServletResponse getResp() {
		return resp;
	}

	public Token setResp(HttpServletResponse resp) {
		this.resp = resp;
		return this;
	}
	
	public List<String> getDepartments() {
		return departments;
	}

	public Token setDepartments(List<String> departments) {
		this.departments = departments;
		return this;
	}

	public long getTimestamp() {
		return timestamp;
	}

	public Token setTimestamp(long timestamp) {
		this.timestamp = timestamp;
		return this;
	}

	public long getUserCreateTime() {
		return userCreateTime;
	}

	public Token setUserCreateTime(long userCreateTime) {
		this.userCreateTime = userCreateTime;
		return this;
	}

	public String getVersion() {
		return version;
	}

	public Token setVersion(String version) {
		this.version = version;
		return this;
	}

	public Long getRemindTime() {
		return remindTime;
	}

	public Token setRemindTime(Long remindTime) {
		this.remindTime = remindTime;
		return this;
	}

	public boolean isNewsletterState() {
		return newsletterState;
	}

	public Token setNewsletterState(boolean newsletterState) {
		this.newsletterState = newsletterState;
		return this;
	}

	public boolean isFrontPageState() {
		return frontPageState;
	}

	public Token setFrontPageState(boolean frontPageState) {
		this.frontPageState = frontPageState;
		return this;
	}

	public boolean isBusinessState() {
		return businessState;
	}

	public Token setBusinessState(boolean businessState) {
		this.businessState = businessState;
		return this;
	}

	public boolean isSettingState() {
		return settingState;
	}

	public Token setSettingState(boolean settingState) {
		this.settingState = settingState;
		return this;
	}

	public String getExtContent() {
		return extContent;
	}

	public Token setExtContent(String extContent) {
		this.extContent = extContent;
		return this;
	}

	@Override
	public String toString() {
		StringBuilder buf = new StringBuilder();
		
		buf.append("token:[");
		buf.append("sessionId=").append(sessionId);
		buf.append(", companyNo=").append(companyNo);
		buf.append(", companyName=").append(companyName);
		buf.append(", suiteId=").append(suiteId);
		buf.append(", uuid=").append(uuid);
		buf.append(", remindTime=").append(remindTime);
		buf.append(", settingState=").append(settingState);
		buf.append(", businessState=").append(businessState);
		buf.append(", frontPageState=").append(frontPageState);
		buf.append(", newsletterState=").append(newsletterState);
		buf.append(", cropPattern=").append(cropPattern);
		buf.append(", userId=").append(userId);
		buf.append(", username=").append(username);


		buf.append("]");


		return buf.toString();
	}
	
	public JSONObject toJSON() {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("sessionId", sessionId);
		jsonObject.put("companyNo", companyNo);
		jsonObject.put("companyName", companyName);
		jsonObject.put("departments", toJSONArray(departments));
		jsonObject.put("corpid", corpid);
		jsonObject.put("suiteId", suiteId);
		jsonObject.put("uuid", uuid);
		jsonObject.put("userId", userId);
		jsonObject.put("username", username);
		jsonObject.put("mobile", mobile);
		jsonObject.put("newsletterState", newsletterState);
		jsonObject.put("frontPageState", frontPageState);
		jsonObject.put("businessState", businessState);
		jsonObject.put("settingState", settingState);
		jsonObject.put("remindTime", remindTime);
		jsonObject.put("headUrl", headUrl);
		jsonObject.put("timestamp", timestamp);
		jsonObject.put("userCreateTime", userCreateTime);
		jsonObject.put("roles", toJSONArray(roles));
		jsonObject.put("permissions", toJSONArray(permissions));
		if (Objects.nonNull(userType)) {
			jsonObject.put("type", userType.getId());
		}
		jsonObject.put("version",version);
		jsonObject.put("extContent",extContent);
		jsonObject.put("cropPattern",cropPattern);
		return jsonObject;
	}

	public static Token fromJSON(JSONObject jsonObject) {
		return Token.create()
				.setSessionId(jsonObject.getString("id"))
				.setCompanyNo(jsonObject.getString("companyNo"))
				.setCompanyName(jsonObject.getString("companyName"))
				.setDepartments(toList(jsonObject.getString("departments")))
				.setCorpid(jsonObject.getString("corpid"))
				.setSuiteId(jsonObject.getString("suiteId"))
				.setUuid(jsonObject.getString("uuid"))
				.setUserId(jsonObject.getString("userId"))
				.setUsername(jsonObject.getString("username"))
				.setMobile(jsonObject.getString("mobile"))
				.setTimestamp(jsonObject.getLongValue("timestamp"))
				.setHeadUrl(jsonObject.getString("headUrl"))
				.setRoles(fromJSONAray(jsonObject.getString("roles")))
				.setPermissions(fromJSONAray(jsonObject.getString("permissions")))
				.setUserType(Enums.getEnum(UserType.class, jsonObject.getString("type")))
				.setUserCreateTime(jsonObject.getLongValue("userCreateTime"))
				.setVersion(jsonObject.getString("version"))
				.setExtContent(jsonObject.getString("extContent"))
				.setSettingState(jsonObject.getBooleanValue("settingState"))
				.setFrontPageState(jsonObject.getBooleanValue("frontPageState"))
				.setBusinessState(jsonObject.getBooleanValue("businessState"))
				.setNewsletterState(jsonObject.getBooleanValue("newsletterState"))
				.setCropPattern(jsonObject.getString("cropPattern"))
				.setRemindTime(jsonObject.getLong("remindTime"));
	}
	
	public static Token create() {
		return new Token();
	}
	
	public static String toJSONArray(Collection<String> permissions) {
		if (Objects.isEmpty(permissions)) {
			return "";
		}
		
		return String.join(",", permissions);
	}
	
	public static Set<String> fromJSONAray(String strs) {
		if (Objects.isEmpty(strs)) {
			return Collections.emptySet();
		}
		
		String[] str = strs.split(",");
		Set<String> set = new HashSet<>(str.length);
		for (int i = 0, j = str.length; i < j; i ++) {
			set.add(str[i]);
		}
		
		return set;
	}
	
	public static List<String> toList(String strs) {
		if (Objects.isEmpty(strs)) {
			return Collections.emptyList();
		}
		
		String[] str = strs.split(",");
		List<String> list = new ArrayList<>(str.length);
		for (int i = 0, j = str.length; i < j; i ++) {
			list.add(str[i]);
		}
		
		return list;
	}

	public String getOldKhtUrl() {
		return oldKhtUrl;
	}

	public void setOldKhtUrl(String oldKhtUrl) {
		this.oldKhtUrl = oldKhtUrl;
	}

	public String getCropPattern() {
		return cropPattern;
	}

	public Token setCropPattern(String cropPattern) {
		this.cropPattern = cropPattern;
		return this;
	}
}
